package com.lge.pitchingcoins.ui.clients.playgame;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;

import com.lge.pitchingcoins.R;
import com.lge.pitchingcoins.util.PitchingCoinsLog;
import com.lge.pitchingcoins.util.Util;
import com.lge.pitchingcoins.util.sessions.ClientsSession;
import com.lge.pitchingcoins.util.sessions.GameCmdManager;
import com.lge.pitchingcoins.util.sessions.GameCmdManager.GameCmdSendDTO;
import com.lge.pitchingcoins.util.sessions.GameCmdProcessor;

import java.util.ArrayList;

@Deprecated
public class PlayGameForClientsActivity extends Activity {
    public static final int CHANGE_IS_GAME_PLAYING = 1000;
    public static final int MAX_COUNT = 20;

    private ArrayList<AccelValue> arValue = new ArrayList<AccelValue>();

    private Activity mActivity = null;
    private GameCmdManager mGameCmdManager = null;
    private GameCmdProcessor mGameCmdProcessor = null;
    private ClientsSession clientsSession = null;
    private String clientNickName = null;

    private Dialog waitingResponseDialog = null;

    private boolean isGamePlaying = false;

    private GamePlayView gamePlayView = null;

    private SensorManager mSensorManager = null;
    private long mApplyTime = 0;
    private int mSenGap = 3000;
    private int force = 0;
    private int LIMIT_FORCE = 20;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == CHANGE_IS_GAME_PLAYING) {
                Util.setHomeKeyLock(mActivity, isGamePlaying);

                if (isGamePlaying) {
                    waitingResponseDialog.dismiss();
                } else {
                    waitingResponseDialog.show();
                }
            }
        }
    };

    SensorEventListener mSensorListener = new SensorEventListener() {
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {

        }

        @Override
        public void onSensorChanged(SensorEvent event) {
            sensorChanged(event);
        }
    };

    // Getters and Setters
    public boolean isGamePlaying() {
        return isGamePlaying;
    }

    public void setGamePlaying(boolean isGamePlaying) {
        this.isGamePlaying = isGamePlaying;

        mHandler.sendEmptyMessage(CHANGE_IS_GAME_PLAYING);
    }

    // Callback Methods
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_play_game_for_clients);

        initComponent();
    }

    @Override
    protected void onStart() {
        PitchingCoinsLog.d("[LifeCycle] ---- onStart()");

        super.onStart();
    }

    @Override
    protected void onResume() {
        PitchingCoinsLog.d("[LifeCycle] ---- onResume()");

        if (clientsSession == null) {
            PitchingCoinsLog.d("Enter onResume() first time");
            Intent intent = getIntent();
            Bundle bundle = intent.getExtras();

            clientsSession = new ClientsSession(this, bundle.getString("ipAddress"), bundle.getInt("port"));

            waitingResponseDialog.show();
        }

        super.onResume();
    }

    @Override
    protected void onPause() {
        PitchingCoinsLog.d("[LifeCycle] ---- onPause()");

        super.onPause();
    }

    @Override
    protected void onDestroy() {
        PitchingCoinsLog.d("[LifeCycle] ---- onDestroy()");

        if (clientsSession != null) {
            clientsSession.sendMessageToServer("IL " + clientNickName);
            clientsSession = null;
        }

        mSensorManager.unregisterListener(mSensorListener);
        super.onDestroy();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
        case KeyEvent.KEYCODE_BACK:
            if (isGamePlaying) {
                //                Toast.makeText(getApplicationContext(), getString(R.string.cannotExitWhenPlayingGame), Toast.LENGTH_SHORT).show();
                return isGamePlaying;
            }
        }

        return super.onKeyDown(keyCode, event);
    }

    public void onMessageReceived(String message) {
        PitchingCoinsLog.d("Client: " + message);

        if (message.equals("IL")) {
            clientsSession = null;
            finish();
        } else if (message.equals("WRU")) {
            sendMessageToServer("IM " + clientNickName);
            PitchingCoinsLog.d("IM " + clientNickName);
        } else if (message.equals("GS")) {
            setGamePlaying(true);
        } else if (message.equals("GO")) {
            setGamePlaying(false);
        }

        // TODO get server message

    }

    // Member Methods
    public void initComponent() {
        mActivity = this;

        clientNickName = getIntent().getExtras().getString("nickname");
        clientNickName += "_" + Build.ID;

        gamePlayView = (GamePlayView)findViewById(R.id.gamePlayView);

        waitingResponseDialog = new Dialog(this);
        waitingResponseDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        waitingResponseDialog.setContentView(R.layout.view_circle_progress_bar);
        waitingResponseDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
        waitingResponseDialog.setOnCancelListener(new OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialogInterface) {
                mActivity.finish();
            }
        });

        mGameCmdManager = GameCmdManager.getInstance();
        mGameCmdProcessor = GameCmdProcessor.getInstance();

        mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);
    }

    public void sendMessageToServer(String message) {
        PitchingCoinsLog.d("sendMessageToServer");
        if (clientsSession != null) {
            clientsSession.sendMessageToServer(message);
        }
    }

    public void sendMessageToServer(float x, float y, float z, int force) {
        GameCmdSendDTO data = mGameCmdManager.new GameCmdSendDTO(clientNickName, x, y, z, force);
        String message = data.toJSONString();
        PitchingCoinsLog.d(message);

        sendMessageToServer(message);
    }

    public void sensorChanged(SensorEvent event) {
        switch (event.sensor.getType()) {
        case Sensor.TYPE_ACCELEROMETER:
            AccelValue accelValue = new AccelValue();
            accelValue.value[0] = event.values[0];
            accelValue.value[1] = event.values[1];
            accelValue.value[2] = event.values[2];
            accelValue.time = event.timestamp;

            if (arValue.size() == MAX_COUNT) {
                arValue.remove(0);
            }
            arValue.add(accelValue);

            long now = System.currentTimeMillis();

            if (now - mApplyTime < mSenGap) {
                break;
            }

            float[] min = new float[] { 100, 100, 100 };
            float[] max = new float[] { -100, -100, -100 };
            float[] difference = new float[3];

            for (int i = arValue.size() - 1; i >= 0; i--) {
                AccelValue v = arValue.get(i);
                for (int j = 0; j < 3; j++) {
                    min[j] = Math.min(min[j], v.value[j]);
                    max[j] = Math.max(max[j], v.value[j]);
                }
            }

            for (int j = 0; j < 3; j++) {
                difference[j] = Math.abs(max[j] - min[j]);
            }

            force = (int)(Math.abs(difference[0] + difference[1] + difference[2]) / 3);

            if (force >= LIMIT_FORCE) {
                mApplyTime = now;

                PitchingCoinsLog.d("getState : " + gamePlayView.mBasedView.getThread().getState());

                if (gamePlayView.mBasedView.getThread().getState() == null) {
                    PitchingCoinsLog.d("playView.mBasedView.getThread().getState() =  null");
                }
                
                if ((gamePlayView.mBasedView.getThread().getState()).equals("TERMINATED")) {
                    PitchingCoinsLog.d("thread reStart");
                    gamePlayView.mBasedView.getThread().start();
                }
                
                if (force != 0) {
                    sendMessageToServer(difference[0], difference[1], difference[2], force);
                    gamePlayView.mBasedView.setMoveSpeed(force);
                    force = 0;
                }
            }
            break;
        }
    }

    
    // Inner Classes
    class AccelValue {
        float[] value = new float[3];
        long time = 0;
    }
}